package com.example.demo;

/**
 * @ClassName WXCore
 * @Description TODO
 * @Author admin
 * @Date 2021/9/24 14:42
 * @Version 1.0
 */

import com.alibaba.fastjson.JSON;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;

import org.springframework.util.Base64Utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;


/**
 * 封装对外访问方法
 *
 * @author liuyazhuang
 */
public class WXCore {

    private static final String WATERMARK = "watermark";
    private static final String APPID = "appid";

    /**
     * 解密数据
     *
     * @return
     * @throws Exception
     */
    public static String decrypt(String appId, String encryptedData, String sessionKey, String iv) {
        String result = "";
        try {
            AES aes = new AES();
            byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
            if (null != resultByte && resultByte.length > 0) {
                result = new String(WxPKCS7Encoder.decode(resultByte));
                JSONObject jsonObject = JSONObject.fromObject(result);
                String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString(APPID);
                if (!appId.equals(decryptAppid)) {
                    result = "";
                }
            }
        } catch (Exception e) {
            result = "";
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 获取手机号流程 小程序端把code发给后台,
     * 后台通过以下微信提供的接口获取session_key 参数有 appid, secret, js_code(这就是传来的code), grant_type=authorization_code(不变的默认值)
     * https://api.weixin.qq.com/sns/jscode2session
     * 返回 用户的openid, session_key(会话密钥), unionid
     * 后台获取session_key 和 前端获取encryptedData和iv 无先后顺序 但是前端获取一定要先获取code在授权手机号(前端是有顺序的)
     * 最后后台通过以下四个参数获取到用户手机号
     */
    public static void main(String[] args) throws Exception {
        String appId = "wx844719fb91269450";
        String encryptedData = "B2Z6HVGeUTnjk1EALoQPEngFN5wv5e2Nt39LP2vtBoYtEwt8AMeXHblpJwkFgWLLY86rCdeSnYt/XIFdPJzfcBp4m6STtvYE2UyohfEnipGljXSWq1OdFIUhtfrO6BZEV1rSZxVRsHWZNHvnalWoqvZP0ITSod69sr3E5gLbRx6bsf4Hp7S2MygULZ6Z4BlL1XQAFErZ6XqNfo9Vw55V7Q==";
        String sessionKey1 = "eEEWK2irrvZXwZE5M2UU9A==";
        String iv = "Wdh9/jNf2bMOu2dLvve+vQ==";
        //两种方式解密
        //第一种发方式
        System.out.println(decrypt(appId, encryptedData, sessionKey1, iv));
        //第二种方式
        byte[] encrypData = Base64Utils.decodeFromString(encryptedData);
        byte[] ivData = Base64Utils.decodeFromString(iv);
        byte[] sessionKey = Base64Utils.decodeFromString(sessionKey1);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(sessionKey, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        String resultString = new String(cipher.doFinal(encrypData), StandardCharsets.UTF_8);
        HashMap hashMap = JSON.parseObject(resultString, HashMap.class);
        System.out.println(hashMap.get("phoneNumber"));
        System.out.println(resultString);
    }
}
